﻿namespace WLFramework.Web.Binder
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using WLFramework.Data;
    using WLFramework.Reflection;
    using WLFramework.Reflection.Metadata;
    using WLFramework.Validation;
    
    public class ModelMetadataProvider : IModelMetadataProvider
    {
        public ICollection<ModelMemberInfo> GetMembers(Type  type)
        {
            Shield.AssertNotNull(ref type, "type");
            Shield.AssertIsNotTrue(type.IsPrimitiveType(), "type");

            List<ModelMemberInfo> props = new List<ModelMemberInfo>();

            var supportProps = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
                                   .Where(k => k.CanRead && k.CanWrite);

            foreach (var p in supportProps)
            {
                ModelMemberInfo member = ModelMemberInfo.Create(p);
                member.Column = p.GetAttribute<ColumnAttribute>(true);
                member.Ignore = p.GetAttribute<IgnoreAttribute>(true);
                member.Display = p.GetAttribute<DisplayAttribute>(true);

                ValidationAttribute[] froms = p.GetAttributes<ValidationAttribute>(true);
                ValidationAttribute required = froms.Where(k => k is RequiredAttribute).FirstOrDefault();

                if (required == null)
                {
                    if (p.PropertyType.IsValueType && !p.PropertyType.IsNullable())
                    {
                        required = new RequiredAttribute();
                    }
                }

                member.Required = required;
                member.Validations.AddRange(froms.Where(k => !(k is RequiredAttribute)).OrderBy(k => (int)k.Priority));

                props.Add(member);
            }

            return props;
        }
    }
}
